package ru.spbau.bytecode.graph;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import ru.spbau.bytecode.geom.Segment;


public class Edge {
	private final Vertex firstVertex;
	private final Vertex secondVertex;
	
	private Color color = Color.black;	// default color
	
	
	public Edge(Vertex v1, Vertex v2) {
		firstVertex = v1;
		secondVertex = v2;
	}
	
	public Vertex getSourceVertex() {
		return firstVertex;
	}
	
	public Vertex getTargetVertex() {
		return secondVertex;
	}
	
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof Edge)) {
			return false;
		}
		
		Edge e = (Edge) o;
		return (e.getSourceVertex().equals(firstVertex) &&
				e.getTargetVertex().equals(secondVertex));
	}
	
	@Override
	public int hashCode() {
		return 13 * firstVertex.hashCode() + 31 * secondVertex.hashCode();
	}
	
	
	public void setColor(Color color) {
		this.color = color;
	}
	
	public Color getColor() {
		return color;
	}
	
	public void draw(Graphics g) {
		Vertex v = getSourceVertex();
		Vertex u = getTargetVertex();
		
		int r = 5;
		
		if (v.isVisible() && u.isVisible()) {
			Point cv = v.getCenter();
			Point cu = u.getCenter();
			Segment s = new Segment(cv, cu);
			Point p1 = v.getEdgeEndpoint(s);
			Point p2 = u.getEdgeEndpoint(s);
			if (p1 != null && p2 != null &&
					Math.hypot(cv.x - p1.x, cv.y - p1.y) <
					Math.hypot(cv.x - p2.x, cv.y - p2.y)) {
				g.drawLine(p1.x, p1.y, p2.x, p2.y);

				//drawing arrow
				int dx = (p2.x - p1.x) / 5;
				int dy = (p2.y - p1.y) / 5;
				
				double d = Math.max(Math.abs(dx), Math.abs(dy)) / 20.0;
				if (d > 1) {
					dx /= d;
					dy /= d;
				}
				
				int a = p1.x - p2.x;
				int b = p2.y - p1.y;
				
				if (b == 0) {
					g.drawLine(p2.x, p2.y, p2.x - dx, p2.y - dy + r);
					g.drawLine(p2.x, p2.y, p2.x - dx, p2.y - dy - r);
				} else if (a == 0) {
					g.drawLine(p2.x, p2.y, p2.x - dx + r, p2.y - dy);
					g.drawLine(p2.x, p2.y, p2.x - dx - r, p2.y - dy);
				} else {
					double angle = Math.atan(a * 1.0 / b);
					g.drawLine(p2.x, p2.y, (int)(p2.x - dx + r * Math.cos(angle)), (int)(p2.y - dy + r * Math.sin(angle)));
					g.drawLine(p2.x, p2.y, (int)(p2.x - dx - r * Math.cos(angle)), (int)(p2.y - dy - r * Math.sin(angle)));
				}
			}
		}
	}
	
	public String toString() {
		return getSourceVertex().getName() + " " + getTargetVertex().getName();
	}
}
